/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Database;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Zen
 */
public class Table implements Serializable{
    private List<Column> columns;
    private PrimaryKey primaryKey;
    private List<ForeignKey> foreignKey;
    private String name;

    public Table(String name)
    {        
        foreignKey = new ArrayList<ForeignKey>();
        columns = new ArrayList<Column>();        
        this.name=name;
        primaryKey = null;
    }
    
    public String getName() 
    {
        return name;
    }
    
    public void setName(String name) 
    {
        this.name = name;
    }
    
    public List<Column> getColumns() 
    {
        return columns;
    }

    public void setColumns(List<Column> columns) 
    {
        this.columns = columns;
    }

    public PrimaryKey getPrimaryKey() 
    {
        return primaryKey;
    }
    public int getColumnIndex(String colName)
    {
        for(int i=0;i<columns.size();i++)
        {  
            if(columns.get(i).getName().toLowerCase().equals(colName.toLowerCase()))
                return i;
        }
        return -1;
    }
    public boolean addPKColumn(String pkKeyColumn)
    {
        int colIdx = getColumnIndex(pkKeyColumn);
        if(colIdx!=-1)
        {
            if(primaryKey==null)
            {
                primaryKey = new PrimaryKey("pk_"+name);
            }
            if(primaryKey.addPKColumn(pkKeyColumn))
            {
                //set allow null
                columns.get(colIdx).setAllowNull(false);
                return true;
            }            
        }        
        return false;
    }
    public void removePrimaryKey()
    {
        primaryKey = null;
    }
    public boolean removePKColumn(String pkKeyColumn)
    {
        return primaryKey.removePKColumn(pkKeyColumn);
    }
    public boolean removeElementForeginKey(String fkKeyName)
    {
        for(int i=0;i<foreignKey.size();i++)
        {
            if(fkKeyName.toLowerCase().equals(foreignKey.get(i).getName().toLowerCase()))
            {
                foreignKey.remove(i);
                return true;
            }
        }
        return false;
    }
    public boolean addElementForeignKey(ForeignKey key)
    {
        for(int i=0;i<foreignKey.size();i++)
        {
            if(key.getName().toLowerCase().equals(foreignKey.get(i).getName().toLowerCase()))
            {
                return false;
            }
        }        
        this.foreignKey.add(key);
        return true;
    }
    
    public List<ForeignKey> getForeignKey() 
    {
        return foreignKey;
    }

    //Kiểm tra column đã tồn tại trong table chưa
    public boolean IsExistColumn(Column column)
    {
        for(int i=0;i<columns.size();i++)
            if(columns.get(i).getName().toLowerCase().equals(column.getName().toLowerCase()))
                return true;
        return false;
    }
    
    //Thêm 1 cột
    public boolean AddColumn(String columnName, Class type, boolean allowNull)
    {
        Column col = new Column(columnName, type, allowNull);
        if(!IsExistColumn(col))
        {
            columns.add(col);
            int nRow = columns.get(0).getData().size();
            for(int i=0;i<nRow;i++)
            {
                columns.get(columns.size()-1).Insert(null);
            }
            return true;
        }            
        return false;
    }
    public boolean isPrimaryKeyColumn(String colName)
    {
        if(primaryKey!=null)
        for(int i=0;i<primaryKey.getPKColumns().size();i++)
        {
            if(colName.toLowerCase().equals(primaryKey.getPKColumns().get(i).toLowerCase()))
            {
                return true;
            }
        }
        return false;
    }
    
    //Xóa 1 cột
    //Truyền vào tên cột
    public boolean RemoveColumn(String colName)
    {
        if(isPrimaryKeyColumn(colName))
            return false;
        for(int i=0;i<columns.size();i++)
            if(columns.get(i).getName().toLowerCase().equals(colName.toLowerCase()))
            {
                columns.remove(i);
                return true;
            }
        return false;
    }
    //Xóa 1 cột
    //Truyền vào vị trí cột
    public boolean RemoveColumn(int index)//Chưa xữ lý primary key / foreign key
    {
        if(isPrimaryKeyColumn(columns.get(index).getName()))
            return false;
        if(index<columns.size())
        {
            columns.remove(index);
            return true;
        }
        return false;
    }
    
    public boolean IsValidForeingKey(List<Object> fkData, List<String> pkColumns)
    {                     
        int count = 0;
        for(int i=0;i<columns.get(0).getData().size();i++)
        {
            for(int j=0;j<columns.size();j++)
            {
                for(int idx=0;idx<pkColumns.size();idx++)
                    if(columns.get(j).getName().toLowerCase().equals(pkColumns.get(idx).toLowerCase()))
                    {
                        if(fkData.get(idx).toString().equals(columns.get(j).GetData(i).toString()))
                            count++;
                        idx++;
                    }
            }
            if(count==fkData.size())
                return true;
        }
        return false;
        
    }
    //Kiểm tra dòng dữ liệu đã tồn tại chưa
    public boolean IsValidData(List<Object> dataRow)
    {
        int nCols=columns.size();
        int nRows=columns.get(0).getData().size(); 
        
        for(int i=0;i<nRows;i++)
        {
            //Kiểm tra trùng dữ liệu, trùng khóa chính            
            int count=0; 
            int pkCount=0;
            for(int j=0;j<nCols;j++)
            {
                if(columns.get(j).getData().get(i)!=null&&dataRow.get(j)!=null)
                {
                    if(columns.get(j).getData().get(i).toString().equals(dataRow.get(j).toString()))
                    {
                        count++;
                    }
                }
                else
                    if(columns.get(j).getData().get(i)==dataRow.get(j))
                    {
                        count++;
                    }
                if(isPrimaryKeyColumn(columns.get(j).getName()))
                {
                    if(columns.get(j).getData().get(i)==dataRow.get(j))
                        pkCount++;
                }
            }
            if(count==nCols)
            {
                return false;
            }
           /* if(primaryKey!=null)
                if(primaryKey.getPKColumns().size()>0&&pkCount==primaryKey.getPKColumns().size())
                    return false;*/
        }         
        if(!CheckAllowNull(dataRow))
            return false;
        return true;        
    }
    //Kiểm tra allow null
    public boolean CheckAllowNull(List<Object> dataRow)
    {
        int nCols=columns.size();
        for(int i=0;i<nCols;i++)
        {
            if(!columns.get(i).getAllowNull())
            {
                if(dataRow.get(i)==null)
                    return false;
            }
        }
        return true; 
    }
    //Thêm 1 dòng dữ liệu
    public boolean InsertRow(List<Object> dataRow)//Xữ lý khóa ngoại ở class Database
    {
        if(IsValidData(dataRow))
        {                        
            for(int i=0;i<columns.size();i++)
            {
                if(!columns.get(i).Insert(dataRow.get(i)))
                {
                    //clear dữ liệu trước đó
                    int size=columns.get(0).getData().size();
                    for(int e=0;e<i;e++)
                    {
                        if(size>0)
                            columns.get(e).RemoveData(size-1);
                    }
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    
    //Xóa 1 dòng dữ liệu
    public boolean RemoveRow(int index)//Xữ lý khóa ngoại ở class Database
    {
        if(index<columns.get(0).getData().size())
        {
            for(int i=0;i<columns.size();i++)
            {
                columns.get(i).RemoveData(index);
            }
            return true;
        }
        return false;
    }
    public boolean SetData(int row, int col,  Object newValue)
    {
        int nCols=columns.size();        
        List<Object> dataRow = new ArrayList<Object>();
        for(int i=0;i<nCols;i++)
        {
            dataRow.add(columns.get(i).getData().get(row));                   
        }
        dataRow.set(col, newValue);
        if(IsValidData(dataRow))
        {
            return columns.get(col).SetData(row, newValue);            
        }
        return false;
    }
    //set 1 dòng dữ liệu
    public boolean SetData(int rowIdx,  List<Object> dataRow)
    {
        if(IsValidData(dataRow))
        {
            for(int i=0;i<columns.size();i++)
            {
                if(!columns.get(i).SetData(rowIdx, dataRow.get(i)))
                    return false;
            }
            return true;
        }
        return false;
    }
            

    
    //Tìm vị trí 1 hàng dữ liệu
    public int getRowIndex(String columnName, Object value)
    {
        for(int i=0;i<columns.size();i++)
            if(columns.get(i).getName().toLowerCase().equals(columnName.toLowerCase()))
                return columns.get(i).getRowIndex(value);
        return -1;
    }
    
    //Kiểm tra có tồn tại cột với tên columnName
    public boolean IsExistColumn(String columnName)
    {
        for(int i=0;i<columns.size();i++)
        {
            if(columnName.toLowerCase().equals(columns.get(i).getName().toLowerCase()))
            {
                return true;
            }
        }
        return false;
    }
        
}
